package view;

import java.awt.Container;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowListener;
import java.util.Properties;
import java.util.ResourceBundle;
import javax.swing.JButton;
import javax.swing.JCheckBoxMenuItem;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumn;
import javax.swing.table.TableModel;
import javax.swing.table.TableRowSorter;
import model.ColourTableCellRenderer;
import model.LogModel;
import model.MyTableModel;

public class LogView extends JFrame {

	private static final long serialVersionUID = 1L;
	private JMenuBar mBar;
	private Container content;
	private ResourceBundle rLabels;
	private StatusBar statusBar;
	private JTable taula;
	private JTextField filtre;
	private JButton aplicarFiltre;
	private TableRowSorter<TableModel> sorter;
	private Object[][] tData;
	private JButton bLoadLogs;
	private JLabel lTitle;
	private TableColumn column;
	private DefaultTableModel tModel;
	private TableCellRenderer colourRenderer;
	private TableColumn tColumn;
	private Properties configFile;
	private String sLanguage;
	private JMenuItem editPreferencesItem;
	private JMenuItem aboutItem;
	private JMenuItem exportItem;
	private JCheckBoxMenuItem showSBItem;
	private JMenuItem quitItem;
	private String[][] sLogs;

	public LogView(LogModel model) {
		super();
		rLabels = model.getLabels();
		configFile = model.getConfigFile();
		/* Auxiliary variables */
		String[] sTableHeader = {
				rLabels.getString("tableFirstColumn"),
				rLabels.getString("tableSecondColumn"),
				rLabels.getString("tableThirdColumn"),
				rLabels.getString("tableFourthColumn") };

		//TODO Delete this test data when the development is finished.
		tData = new Object[][] {
			//	{"t11", "WARN", "t13", "a" },
			//	{"t21", "INFO", "t23", "b" },
			//	{"t31", "ERROR", "t33", "a" }
		};

		/* Initialize GUI Components */
		filtre = new JTextField(70);
		aplicarFiltre = new JButton(rLabels.getString("applyFilter"));
		bLoadLogs = new JButton(rLabels.getString("loadLogs"));
		mBar = new JMenuBar();
		lTitle = new JLabel("<html><font color=\"blue\">" + configFile.getProperty("applicationName") + "</font> <i><small>" + configFile.getProperty("applicationVersion") + "</small></i></html>");
		tModel = new MyTableModel(tData, sTableHeader);
		taula = new JTable(tModel);
		sorter = new TableRowSorter<TableModel>(taula.getModel());
		JScrollPane scrollPane = new JScrollPane(taula);
		statusBar = new StatusBar(rLabels);
		colourRenderer = new ColourTableCellRenderer();
		sLogs = null;

		/* Configure GUI Components */
		lTitle.setFont(new Font("Verdana", Font.BOLD, 16));
		taula.setAutoCreateRowSorter(true);
		taula.setRowSorter(sorter);
		scrollPane.setPreferredSize(new Dimension(850, 400));
		taula.setFillsViewportHeight(true);
		this.setJMenuBar(mBar);
		this.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);

		/* Set layout */
		GridBagLayout grid = new GridBagLayout();
		content = this.getContentPane();
		content.setLayout(grid);
		GridBagConstraints c = new GridBagConstraints();
		c.ipadx = 2; c.ipady = 2; c.weightx = 1; c.weighty = 1;

		/* The initial table data is rendered */
		for(int i = 0; i < 4; i++) {
			tColumn = taula.getColumnModel().getColumn(i);
			tColumn.setCellRenderer(colourRenderer);
		}

		/* Column reordering is not allowed */
		taula.getTableHeader().setReorderingAllowed(false);

		/* This applies some changes to the columms */
		setColumns();

		/* Add components to the container */
		c.gridy = 0; c.gridx = 0; c.gridwidth = 2;
		grid.setConstraints(lTitle, c);
		content.add(lTitle, c);

		c.gridx = 2; c.gridy = 0; c.gridwidth = 1;
		grid.setConstraints(bLoadLogs, c);
		content.add(bLoadLogs, c);

		c.gridy = 1; c.gridx = 0; c.gridwidth = 3;
		grid.setConstraints(scrollPane, c);
		content.add(scrollPane, c);

		c.gridwidth = 1; c.gridy = 2; c.gridx = 1;
		c.anchor = GridBagConstraints.NORTHEAST;
		grid.setConstraints(filtre, c);
		content.add(filtre, c);

		c.gridy = 2; c.gridx = 2; c.gridwidth = 1;
		c.anchor = GridBagConstraints.NORTHWEST;
		grid.setConstraints(aplicarFiltre, c);
		content.add(aplicarFiltre, c);

		c.gridy = 3; c.gridx = 0; c.gridwidth = 3;
		c.fill = GridBagConstraints.HORIZONTAL;
		c.anchor = GridBagConstraints.PAGE_END;
		grid.setConstraints(statusBar, c);
		content.add(statusBar, c);

		/* Set the size of the window */
		content.setPreferredSize(new Dimension(900, 700));

		/* This sizes the frame */
		this.pack();
	}
	
	public Properties getConfigFile() {
		return configFile;
	}
	
	public String getLanguage() {
		return sLanguage;
	}
	
	public void setLanguage(String sLanguage) {
		this.sLanguage = sLanguage;
	}

	public void setColumns() {
		int width = 0;
		for (int i = 0; i < 4; i++) {
		    if (i == 0 || i == 2) width = 150;
		    else if (i == 1) width = 100;
		    else if (i == 3) width = 450;

			column = taula.getColumnModel().getColumn(i);
		    column.setResizable(false);
		    column.setWidth(width); column.setMinWidth(width);
		    column.setMaxWidth(width); column.setWidth(width);
	        column.setPreferredWidth(width); 
		}
	}
	
	public void addWinListener(WindowListener window) {
		this.addWindowListener(window);
	}
	
	public void addFilterListener(ActionListener filter) {
		aplicarFiltre.addActionListener(filter);
	}
	
	public void addLoadLogsListener(ActionListener loadLogs) {
		bLoadLogs.addActionListener(loadLogs);
	}
	
	public String getTextFiltre() { return filtre.getText(); }
	
	public TableRowSorter<TableModel> getSorter() { return this.sorter; }
	
	public String[][] getLogs() {
		return this.sLogs;
	}
	
	public void setLogs(String[][] sLogs) {
		this.sLogs = sLogs;
		/* First we clean the table */
		while(tModel.getRowCount() > 0) tModel.removeRow(0);
		/* Then we fill it again with the new fetched data */
		for(String[] sLog : sLogs) tModel.insertRow(0, sLog);
	}

	public Container getContent() { return content; }

	public void createMenuBar() {
		JMenu fileMenu = new JMenu(rLabels.getString("menuFile"));
		JMenu editMenu = new JMenu(rLabels.getString("menuEdit"));
		JMenu viewMenu = new JMenu(rLabels.getString("menuView"));
		JMenu helpMenu = new JMenu(rLabels.getString("menuHelp"));

		aboutItem = new JMenuItem(rLabels.getString("menuAbout"));
		exportItem = new JMenuItem(rLabels.getString("menuExport"));
		exportItem.setEnabled(false);
		quitItem = new JMenuItem(rLabels.getString("menuExit"));
		JMenuItem cleanSBItem = new JMenuItem(rLabels.getString("menuCleanStatusBar"));
		editPreferencesItem = new JMenuItem(rLabels.getString("menuPreferences"));
		showSBItem = new  JCheckBoxMenuItem(rLabels.getString("menuShowSB"), true);

		fileMenu.setMnemonic('F'); viewMenu.setMnemonic('V');
		helpMenu.setMnemonic('H');
		mBar.add(fileMenu); mBar.add(editMenu);
		mBar.add(viewMenu); mBar.add(helpMenu);
		
		editMenu.add(editPreferencesItem);
		fileMenu.add(exportItem);
		fileMenu.addSeparator();
		fileMenu.add(quitItem);
		viewMenu.add(cleanSBItem); viewMenu.addSeparator();
		viewMenu.add(showSBItem);
		helpMenu.add(aboutItem);
		
		cleanSBItem.addActionListener(new CleanSBAction());
		
	}
	
	public JMenuItem getExportItem() {
		return exportItem;
	}
	
	public JMenuItem getQuitItem() {
		return quitItem;
	}
	
	public JMenuItem getEditPreferencesItem() {
		return editPreferencesItem;
	}
	
	public JMenuItem getAboutItem() {
		return aboutItem;
	}

	class CleanSBAction implements ActionListener {
		public void actionPerformed(ActionEvent e) {
			statusBar.setMessage(rLabels.getString("statusReady"));
		}
	}

	public void setLabels(ResourceBundle rLabels) {
		this.rLabels = rLabels;
	}
	
	public JCheckBoxMenuItem getShowSBItem() {
		return this.showSBItem;
	}
	
	public StatusBar getStatusBar() {
		return this.statusBar;
	}
}
